import fs from 'fs'
import ref from 'ref'
import FaceFR from '../../../sdk/arcface/FaceFR'
import FaceBase from '../../../sdk/arcface/FaceBase'
import {config} from '@/common/utils'
import {db} from './db'

const softconfig = config.get('softconfig')
const userDb = db.open('users')

/**
 * 获取用户列表
 * @returns {Promise<any>}
 */
export function getUserList() {
  return new Promise((resolve, reject) => {
    userDb.find({}, (err, list) => {
      if (err) {
        reject(err)
      } else {
        list.forEach((val, index) => {
          let face_dat_path = `${softconfig.face_dat_path + val._id}.dat`
          let stats = fs.existsSync(face_dat_path)
          list[index].face_dat = stats ? face_dat_path : '不存在'
          list[index].face_img = `${softconfig.face_img_path + val._id}.jpg`
          readFace(list[index].face_dat, faceFeature => {
            list[index].faceFeature = faceFeature
          })
        })
        resolve(list)
      }
    })
  })
}

/**
 * 添加用户
 * @param doc
 * @returns {Promise<any>}
 */
export function addUser(doc) {
  return new Promise((resolve, reject) => {
    userDb.insert(doc, (err, data) => {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
}

/**
 * 更新用户
 * @param query
 * @param update
 * @returns {Promise<any>}
 */
export function updateUser(query, update) {
  return new Promise((resolve, reject) => {
    userDb.update(query, update, {}, (err, numReplaced) => {
      if (err) {
        reject(err)
      } else {
        resolve(numReplaced)
      }
    })
  })
}

/**
 * 删除用户
 * @param _id
 * @returns {Promise<any>}
 */
export function removeUser(data) {
  return new Promise((resolve, reject) => {
    userDb.remove({_id: data._id}, {}, (err, numRemoved) => {
      if (err) {
        reject(err)
      } else {
        try {
          fs.unlink(data.face_dat, err => {
            if (err) throw err
          })
          fs.unlink(data.face_img, err => {
            if (err) throw err
          })
        } catch (e) {
          reject(e)
        }
        resolve(numRemoved)
      }
    })
  })
}

/**
 * 保存人脸特征文件
 * @param name
 * @param face_dat
 * @param face_img
 * @returns {Promise<any>}
 */
export function saveFaceFeature(name, face_dat, face_img) {
  return new Promise((resolve, reject) => {
    // 人脸特征
    let datData = Buffer.alloc(face_dat.lFeatureSize)
    FaceBase.memcpy(datData.address(), face_dat.pbFeature.address(), face_dat.lFeatureSize)
    fs.writeFile(`${softconfig.face_dat_path + name}.dat`, datData, err => {
      reject(err)
    })
    // 人脸照片
    let imgData = Buffer.from(face_img.replace(/.+,/, ''), 'base64')
    fs.writeFile(`${softconfig.face_img_path + name}.jpg`, imgData, err => {
      reject(err)
    })
    resolve()
  })
}

/**
 * 脸部特征比较
 * @param hEngine
 * @param reffeature
 * @param probefeature
 * @returns {Promise<any>}
 * @constructor
 */
export function FacePairMatching(hEngine, reffeature, probefeature, uindex) {
  return new Promise((resolve, reject) => {
    let pfSimilScore = Buffer.alloc(ref.sizeof.float)
    pfSimilScore.type = ref.refType(ref.types.float)
    pfSimilScore.writeFloatLE(0, 0.0)
    let ret = FaceFR.AFR_FSDK_FacePairMatching(hEngine, reffeature.ref(), probefeature.ref(), pfSimilScore)
    if (ret !== 0) {
      reject(ret)
    }
    resolve({uindex, score: pfSimilScore.readFloatLE(0)})
  })
}

/**
 * 读取人脸特征文件
 * @param file
 * @param callback
 */
function readFace(file, callback) {
  if (file !== '不存在') {
    fs.readFile(file, (err, data) => {
      if (err) throw callback(null)
      // 提取的脸部特征信息
      let faceFeature = new FaceFR.AFR_FSDK_FACEMODEL()
      faceFeature.lFeatureSize = data.length
      faceFeature.pbFeature = data
      callback(faceFeature)
    })
  }
}
